import type {
  ComponentRecordType,
  GenerateMenuAndRoutesOptions,
  RouteMeta,
  RouteRecordStringComponent,
} from '@vben/types';

import type { AuthApi } from '#/api/types';

import { generateAccessible } from '@vben/access';
import { preferences } from '@vben/preferences';

import { message } from 'ant-design-vue';
import { cloneDeep } from 'lodash-es';

import { getRouteListApi } from '#/api';
import { BasicLayout, IFrameView } from '#/layouts';
import { $t } from '#/locales';

import { localMenuList } from './routes/local';

const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue');
const NotFoundComponent = () => import('#/views/_core/fallback/not-found.vue');

/**
 * 后端返回的meta有时候不包括需要的信息 比如activePath等
 * 在这里定义映射
 */
const routeMetaMapping: Record<string, Omit<RouteMeta, 'title'>> = {
  // 在这里添加特殊路径的元数据配置
  // 例如：
  // '/system/role-auth/user/:roleId(\\d+)': {
  //   activePath: '/system/role',
  //   requireHomeRedirect: true,
  // },
};

/**
 * 后台路由转vben路由
 * @param menuList 后台菜单
 * @param parentPath 上级目录
 * @returns vben路由
 */
function backMenuToVbenMenu(
  menuList: AuthApi.RouteItem[],
  parentPath = '',
): RouteRecordStringComponent[] {
  const resultList: RouteRecordStringComponent[] = [];

  menuList.forEach((menu) => {
    // 处理路径
    let path = menu.path;
    if (parentPath && path) {
      // 确保路径格式一致，如果不是以'/'开头，则添加'/'
      path = path.startsWith('/')
        ? `${parentPath}${path}`
        : `${parentPath}/${path}`;
    } else if (path && !path.startsWith('/')) {
      // 确保单独的路径也是以'/'开头
      path = `/${path}`;
    }

    // 创建vben路由对象
    const vbenRoute: RouteRecordStringComponent = {
      component: menu.component,
      meta: {
        hideInMenu: menu.meta.hideInMenu,
        icon: menu.meta.icon,
        keepAlive: menu.meta.keepAlive,
        title: menu.meta.title,
        order: menu.meta.order,
      },
      name: menu.name,
      path,
    };

    // 处理meta映射
    if (Object.keys(routeMetaMapping).includes(vbenRoute.path)) {
      const routeMeta = routeMetaMapping[vbenRoute.path];
      if (routeMeta) {
        vbenRoute.meta = {
          ...vbenRoute.meta,
          ...(routeMeta as RouteMeta),
        };
      }
    }

    // 处理query参数
    if (menu.meta.query) {
      vbenRoute.meta && (vbenRoute.meta.query = menu.meta.query);
    }

    // 处理外部链接
    if (menu.meta.link) {
      vbenRoute.meta && (vbenRoute.meta.link = menu.meta.href);
    }

    // 处理重定向
    if (menu.redirect) {
      vbenRoute.redirect = menu.redirect;
    }

    // 处理iframe
    if (menu.meta.iframeSrc) {
      vbenRoute.component = 'IFrameView';
      if (vbenRoute.meta) {
        vbenRoute.meta.iframeSrc = menu.meta.iframeSrc;
      }
    }

    // 处理特殊组件类型
    switch (menu.component) {
      case 'BasicLayout':
      case 'Layout': {
        vbenRoute.component = 'BasicLayout';
        break;
      }
      case 'IFrameView': {
        vbenRoute.component = 'IFrameView';
        if (vbenRoute.meta) {
          vbenRoute.meta.iframeSrc = menu.meta.iframeSrc;
        }
        break;
      }
      case 'ParentView': {
        // 三级以上菜单的父级组件，留空让路由系统自动处理
        vbenRoute.component = '';
        break;
      }
      default: {
        // 处理常规组件路径，确保格式正确
        if (menu.component && !menu.component.startsWith('/')) {
          vbenRoute.component = `/${menu.component}`;
        }
        break;
      }
    }

    // 处理子路由
    if (menu.children && menu.children.length > 0) {
      vbenRoute.children = backMenuToVbenMenu(menu.children, path);
    }

    // 添加到结果列表
    resultList.push(vbenRoute);
  });

  return resultList;
}

async function generateAccess(options: GenerateMenuAndRoutesOptions) {
  const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue');

  const layoutMap: ComponentRecordType = {
    BasicLayout,
    IFrameView,
    NotFoundComponent,
  };

  return await generateAccessible(preferences.app.accessMode, {
    ...options,
    fetchMenuListAsync: async () => {
      // 清除以前的message
      message.destroy();
      message.loading({
        content: `${$t('common.loadingMenu')}...`,
        duration: 1,
      });
      // 获取菜单列表
      const menuResult = await getRouteListApi();
      // 将菜单数据转换为路由组件格式
      const vbenMenuList = backMenuToVbenMenu(menuResult.data || menuResult);
      const menuList = [...cloneDeep(localMenuList), ...vbenMenuList];
      return menuList;
    },
    // 可以指定没有权限跳转403页面
    forbiddenComponent,
    // 如果 route.meta.menuVisibleWithForbidden = true
    layoutMap,
    pageMap,
  });
}

export { generateAccess };
